package com.xinggq.user.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinggq.common.context.UserContext;
import com.xinggq.common.enums.EnableEnum;
import com.xinggq.common.page.PageCondition;
import com.xinggq.common.utils.IdGenerator;
import com.xinggq.user.api.dto.userrole.UserRoleCreateRequest;
import com.xinggq.user.api.enums.RoleEnum;
import com.xinggq.user.api.exception.UserCenterException;
import com.xinggq.user.service.dto.role.RoleVO;
import com.xinggq.user.service.dto.user.UserCreateRequest;
import com.xinggq.user.service.dto.user.UserUpdateRequest;
import com.xinggq.user.service.dto.user.UserPageRequest;
import com.xinggq.user.service.dto.user.UserVO;
import com.xinggq.user.service.entity.SysTenantEntity;
import com.xinggq.user.service.entity.SysUserEntity;
import com.xinggq.user.service.mapper.SysUserMapper;
import com.xinggq.user.service.service.RoleService;
import com.xinggq.user.service.service.UserInfoService;
import com.xinggq.user.service.service.UserRoleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 用户信息服务实现类
 *
 * @author xinggq
 * @since 2025/10/30
 */
@Service
@Slf4j
@AllArgsConstructor
public class UserInfoServiceImpl implements UserInfoService {

  private final SysUserMapper userMapper;
  private final PasswordEncoder passwordEncoder;
  private final UserRoleService userRoleService;
  private final RoleService roleService;

  @Override
  public SysUserEntity getUserById(Long userId) {
    return userMapper.selectById(userId);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public UserVO createUser(UserCreateRequest request) {
    log.info("开始创建用户，用户编号: {}", request.username());

    validateUserUniqueness(request);

    SysUserEntity user = buildUserEntity(request);

    int result = userMapper.insert(user);
    if (result <= 0) {
      throw new RuntimeException("用户创建失败");
    }
    log.info("用户创建成功，用户ID: {}", user.getId());
    return UserVO.fromEntity(user);
  }

  @Override
  public void initTenantAdmin(SysTenantEntity tenant) {
    // 根据租户信息创建用户信息
    SysUserEntity user = new SysUserEntity();
    user.setId(IdGenerator.generateId());
    user.setTenantId(tenant.getId());
    user.setUsername(tenant.getTenantCode());
    user.setPasswordHash(passwordEncoder.encode(RoleEnum.TENANT_ADMIN.getInitPassword()));
    user.setRealName(RoleEnum.TENANT_ADMIN.getName());
    user.setNickname(RoleEnum.TENANT_ADMIN.getName());
    user.setStatus(EnableEnum.Y.getCode());
    userMapper.insert(user);
    // 给用户授权超管
    RoleVO roleDetailByCode = roleService.getRoleDetailByCode(RoleEnum.TENANT_ADMIN.getCode());
    UserRoleCreateRequest userRoleCreateRequest = new UserRoleCreateRequest();
    userRoleCreateRequest.setUserId(user.getId());
    userRoleCreateRequest.setRoleId(roleDetailByCode.getId());
    userRoleService.createUserRole(userRoleCreateRequest);
  }

  /**
   * 校验用户唯一性
   */
  private void validateUserUniqueness(UserCreateRequest request) {
    // 校验用户名
    if (existsByUsername(request.username(), null)) {
      throw UserCenterException.userCreateFailed("用户名已存在");
    }

    // 校验邮箱
    if (request.email() != null && !request.email().trim().isEmpty()) {
      if (existsByEmail(request.email(), null)) {
        throw UserCenterException.userCreateFailed("邮箱已存在");
      }
    }

    // 校验手机号
    if (request.phone() != null && !request.phone().trim().isEmpty()) {
      if (existsByPhone(request.phone(), null)) {
        throw UserCenterException.userCreateFailed("手机号已存在");
      }
    }
  }

  /**
   * 根据用户名查询用户
   */
  public SysUserEntity selectByUsername(String username) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getUsername, username)
        .ne(SysUserEntity::getStatus, -1);
    return userMapper.selectOne(queryWrapper);
  }

  /**
   * 根据邮箱查询用户
   */
  public SysUserEntity selectByEmail(String email) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getEmail, email)
        .ne(SysUserEntity::getStatus, -1);
    return userMapper.selectOne(queryWrapper);
  }

  /**
   * 根据手机号查询用户
   */
  public SysUserEntity selectByPhone(String phone) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getPhone, phone)
        .ne(SysUserEntity::getStatus, -1);
    return userMapper.selectOne(queryWrapper);
  }

  /**
   * 检查用户名是否存在
   */
  public boolean existsByUsername(String username, Long excludeId) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getUsername, username)
        .ne(SysUserEntity::getStatus, -1);
    if (excludeId != null) {
      queryWrapper.ne(SysUserEntity::getId, excludeId);
    }
    return userMapper.selectCount(queryWrapper) > 0;
  }

  /**
   * 检查邮箱是否存在
   */
  public boolean existsByEmail(String email, Long excludeId) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getEmail, email)
        .ne(SysUserEntity::getStatus, -1);
    if (excludeId != null) {
      queryWrapper.ne(SysUserEntity::getId, excludeId);
    }
    return userMapper.selectCount(queryWrapper) > 0;
  }

  /**
   * 检查手机号是否存在
   */
  public boolean existsByPhone(String phone, Long excludeId) {
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysUserEntity::getPhone, phone)
        .ne(SysUserEntity::getStatus, -1);
    if (excludeId != null) {
      queryWrapper.ne(SysUserEntity::getId, excludeId);
    }
    return userMapper.selectCount(queryWrapper) > 0;
  }

  @Override
  public boolean existByUserName(String userName, Long excludeUserId) {
    return existsByUsername(userName, excludeUserId);
  }

  /**
   * 构建用户实体
   */
  private SysUserEntity buildUserEntity(UserCreateRequest request) {
    SysUserEntity user = new SysUserEntity();

    // 基本信息
    user.setId(IdGenerator.generateId());
    user.setTenantId(UserContext.getCurrentTenantId());
    user.setUsername(request.username());
    user.setEmail(request.email());
    user.setPhone(request.phone());
    user.setRealName(request.realName());
    user.setNickname(request.nickname());
    user.setGender(request.gender());
    user.setBirthday(request.birthday());
    // 密码加密
    user.setPasswordHash(passwordEncoder.encode(request.password()));

    // 状态设置
    user.setStatus(EnableEnum.Y.getCode());
    user.setLoginCount(0);

    LocalDateTime now = LocalDateTime.now();
    user.setCreatedAt(now);
    user.setUpdatedAt(now);
    user.setCreatedBy(UserContext.getCurrentUserId());
    user.setUpdatedBy(UserContext.getCurrentUserId());

    return user;
  }

  @Override
  public UserVO getUserDetail(Long userId) {
    log.info("获取用户详细信息，用户ID: {}", userId);

    SysUserEntity user = userMapper.selectById(userId);
    if (user == null) {
      throw UserCenterException.userNotFound(String.valueOf(userId));
    }

    return UserVO.fromEntity(user);
  }

  @Override
  public IPage<UserVO> pageQuery(PageCondition<UserPageRequest> pageCondition) {
    UserPageRequest request = pageCondition.getQueryDto();

    // 构建查询条件
    LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<>();

    // 租户ID过滤
    queryWrapper.eq(SysUserEntity::getTenantId, UserContext.getCurrentTenantId());
    // 条件过滤
    if (request != null) {
      if (StringUtils.hasText(request.getUsername())) {
        queryWrapper.like(SysUserEntity::getUsername, request.getUsername());
      }
      if (StringUtils.hasText(request.getEmail())) {
        queryWrapper.like(SysUserEntity::getEmail, request.getEmail());
      }
      if (StringUtils.hasText(request.getPhone())) {
        queryWrapper.like(SysUserEntity::getPhone, request.getPhone());
      }
      if (StringUtils.hasText(request.getRealName())) {
        queryWrapper.like(SysUserEntity::getRealName, request.getRealName());
      }
      if (request.getStatus() != null) {
        queryWrapper.eq(SysUserEntity::getStatus, request.getStatus());
      }
      if (request.getGender() != null) {
        queryWrapper.eq(SysUserEntity::getGender, request.getGender());
      }
    }
    // 排序
    queryWrapper.orderByDesc(SysUserEntity::getCreatedAt);

    // 分页查询
    Page<SysUserEntity> page = new Page<>(pageCondition.getPageNum(), pageCondition.getPageSize());
    IPage<SysUserEntity> userPage = userMapper.selectPage(page, queryWrapper);

    // 转换为VO
    return userPage.convert(UserVO::fromEntity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public UserVO updateUser(UserUpdateRequest request) {
    Long userId = request.getId();
    log.info("更新用户，用户ID: {}", userId);

    SysUserEntity user = userMapper.selectById(userId);
    if (user == null) {
      throw UserCenterException.userNotFound(String.valueOf(userId));
    }

    // 用户名更新与唯一性校验
    if (StringUtils.hasText(request.getUsername()) && !request.getUsername().equals(user.getUsername())) {
      if (existsByUsername(request.getUsername(), userId)) {
        throw UserCenterException.userCreateFailed("用户名已存在");
      }
      user.setUsername(request.getUsername());
    }

    // 邮箱更新与唯一性校验
    if (StringUtils.hasText(request.getEmail()) && !request.getEmail().equals(user.getEmail())) {
      if (existsByEmail(request.getEmail(), userId)) {
        throw UserCenterException.userCreateFailed("邮箱已存在");
      }
      user.setEmail(request.getEmail());
    }

    // 手机号更新与唯一性校验
    if (StringUtils.hasText(request.getPhone()) && !request.getPhone().equals(user.getPhone())) {
      if (existsByPhone(request.getPhone(), userId)) {
        throw UserCenterException.userCreateFailed("手机号已存在");
      }
      user.setPhone(request.getPhone());
    }

    // 其他基本信息更新
    if (StringUtils.hasText(request.getRealName())) {
      user.setRealName(request.getRealName());
    }
    if (StringUtils.hasText(request.getNickname())) {
      user.setNickname(request.getNickname());
    }
    if (request.getGender() != null) {
      user.setGender(request.getGender());
    }
    if (request.getBirthday() != null) {
      user.setBirthday(request.getBirthday());
    }

    // 设置更新人与更新时间
    user.setUpdatedAt(LocalDateTime.now());
    user.setUpdatedBy(UserContext.getCurrentUserId());

    int result = userMapper.updateById(user);
    if (result <= 0) {
      throw UserCenterException.userCreateFailed("用户更新失败");
    }

    log.info("用户更新成功，用户ID: {}", user.getId());
    return UserVO.fromEntity(user);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean enableUser(Long userId) {
    log.info("启用用户，用户ID: {}", userId);
    return changeStatus(userId, EnableEnum.Y);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean disableUser(Long userId) {
    log.info("禁用用户，用户ID: {}", userId);
    return changeStatus(userId, EnableEnum.N);
  }

  @Override
  public boolean delUser(Long userId) {
    log.info("删除用户，用户ID: {}", userId);
    return changeStatus(userId, EnableEnum.D);
  }


  private boolean changeStatus(Long userId, EnableEnum status) {
    SysUserEntity user = userMapper.selectById(userId);
    if (user == null) {
      throw UserCenterException.userNotFound("userId:" + userId);
    }
    if (status.getCode().equals(user.getStatus())) {
      log.warn("用户状态无需更改，用户ID: {}", userId);
      return true;
    }
    user.setStatus(status.getCode());
    user.setUpdatedAt(LocalDateTime.now());
    user.setUpdatedBy(UserContext.getCurrentUserId());
    int result = userMapper.updateById(user);
    boolean success = result > 0;

    if (success) {
      log.info("用户{}成功，用户ID: {}", status.getMsg(), userId);
    } else {
      log.error("用户{}失败，用户ID: {}", status.getMsg(), userId);
    }

    return success;
  }
}
